#pragma once

#include <functional>
#include <sys/socket.h>

class UdpSocketBase;

/*	
 * @brief 	一个UDP Socket的包装类库的对外文件
 * @note 	这是一个简化的版本，有意忽略一些事件，只保留Receive data和Close socket两个事件。
 *		 	demo详见测试用例。
 * @note 本类库使用libuv库和C++11以上标准
 *		
*/
class UdpSocketWrapper {
public: 
	typedef  std::function<void(const uint8_t*, size_t, const struct sockaddr*, UdpSocketWrapper*)> CALL_BACK;	
	typedef  std::function<void(const UdpSocketWrapper*)> ON_CLOSE;
	typedef std::function<void(int, const UdpSocketWrapper*)> ON_SEND_FAILED;
public:
	/*
	 * @brief 获取返回值的描述字符串
	 * @note  该函数主要应用于Listen接口
	*/
	static const char*  GetErrorScript(int error);
public:
	UdpSocketWrapper();
	virtual ~UdpSocketWrapper();
  
public:
	int 	Listen(const char* ip, uint16_t port, const CALL_BACK& onReceive);
	int 	Listen(const char* ip, uint16_t port);
	void 	Destroy();
public:
	void Send(const uint8_t *data, size_t len, const struct sockaddr *addr);
	void Send(const uint8_t *data, size_t len, const char* ip,  uint16_t port);	
	
public:
	const struct sockaddr *GetLocalAddress() const;
	std::string GetLocalIP();
	uint16_t GetLocalPort() const;
	size_t GetRecvBytes() const;
	size_t GetSentBytes() const;
private:
	int Listen(const char* ip, uint16_t port, const CALL_BACK& onReceive, const ON_CLOSE& onClose, const ON_SEND_FAILED& onSendFailed);
private:
	UdpSocketBase* impl {nullptr};
};